#ifndef DEBUG_H_
#define DEBUG_H_

#include <iostream>
#include <sstream>
#include <map>

/*!
	This class provides features used to debug. You can easily enable or disable some special features and associate an ostream for each features, avoiding to overflow the standard output stream (TODO: add some example in the doc).
*/
class Debug
{
	public:
	/*! This struct defines an output stream and a boolean to know if the feature debug is activated or de-activated. */
	typedef struct
	{
		bool enabled;
		std::ostream* outstream;
	} debug_feature_t;

	/*! This enum typedef is a list of all debug features available. The feature list should increase with the time. */
	typedef enum
	{
		VISION_CONE,
		BB_INFO,
		PLAN_INFO,
		MEM_INFO,
		WAYPOINT_SHOW,
		ENTITY_SEEK_TARGET,
		SEEK_DISPLAY
	} debug_t;

	protected:
	std::map<debug_t, debug_feature_t> debug_features__;	/**< The map which associates each feature to an enabled/disabled status and an ostream. */
	std::stringstream dummy_out__;				/**< A dummy output stream, which will never be displayed. */

	/*! Returns true if the given flag is in the map. */
	bool existFlag(debug_t d);
	/*! Created, in the map, the debug feature set with the 'enabled' argument with the dummy output stream. */
	void createFlag(debug_t d, bool enabled);

	public:
	/*! Constructor. Actually does nothing. */
	Debug();
	/*! Destructor. Actually does nothing. */
	virtual ~Debug();

	/*! Set a feature enabled, creating it if needed. */
	void setFlag(debug_t d);
	/*! Set a feature disabled, creating it if needed. */
	void unsetFlag(debug_t d);
	/*! Toffle a feature, creating it to false if it does not exist. */
	void toggleFlag(debug_t d);

	/*! Associates an output stream to a debug feature, creating it if needed. */
	void setFlagStream(debug_t d, std::ostream* os);

	/*! Returns the status of a debug feature, creating it if needed. */
	bool operator[](debug_t d);
	/*! Returns the output stream of a debug feature, creating it if needed. */
	std::ostream& out(debug_t d);
};

/*! global variable 'debug", which can be used from anywhere.  */
extern Debug debug;

#endif

